<?php
/**
 * _.class - tools
 *
 * @version:	0.1a
 * @package:	global
 * @author:	alex_ez
 * @created:	16.02.2009 15:02:27
 *
 * @copyright:	(c) 2009 alex <qfox@ya.ru> yaroshevich aka alex_ez. All rights reserved.
 */



final class _
{
	static public function parse_args($args, $defaults = false) {
		$r = array();

		if ( is_object( $args ) )
			$r = get_object_vars( $args );
		elseif ( is_array( $args ) )
			$r =& $args;
		else
			parse_str( $args, $r );

		if(is_array( $defaults))
			return $r + $defaults;

		return $r;
	}

	static public function extract_args($args, $defaults) {
        $rslt = array();

        $options = _::parse_args($args, $defaults);

        if(is_array($defaults))
            foreach(array_keys($defaults) as $key)
                $rslt[$key] = $options[$key];

        return $rslt;
    }
        
	static public function pick( )
	{
		$_A = func_get_args();
		if( sizeof( $_A ) == 1 && is_array( reset( $_A ) ) ) $_A = reset( $_A );
		
		foreach( array_keys( $_A ) as $k )
		if( isset( $_A[$k] )
		 && !is_null( $_A[$k] ) )
			return $_A[$k];
		
		return null;
	}
	
	static public function pick_any( )
	{
		$_A = func_get_args();
		if( sizeof( $_A ) < 1 ) return null;
		
		return $_A[ rand( 0, sizeof( $_A )-1 ) ];
	}
	
	static public function plural( )
	{
		$args = func_get_args( );
		$f = array_shift( $args );
		if( !is_array( $f ) )
		{
			$f = array( $f );
			while( !is_numeric( reset( $args ) ) && !empty( $args ) )
				$f[] = array_shift( $args );
		}
		$n = array_shift( $args );
		
		$plural_forms = array(
		'ru' => array(
			'nplurals' => 3,
			'plural' => '( (n%10)==1 && (n%100)!=11 ) ? 0 : ( n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2 )'
			),
		);
		
		$l = 'ru';
		$ff = create_function( '$n', 'return '.str_replace( 'n', '$n', $plural_forms[$l]['plural'] ).';' );
		$m = $ff( $n );
		$r = !isset( $f[ $m ] ) ? $f[ $m ] : reset( $f );
		
		return $f[ $m ];
	}

	static public function pluraltext_ru( $n, $s = 'm', $st = null )
	{
		if( !ctype_digit( (string)($n) )
			|| (!empty($st) && sizeof($st) != 3)
			|| !is_string($s) || isset($s[7]) )
			return null;

		$zero = 'ноль';
		$onesbysex = array(
			'm' => array('','один','два','три','четыре','пять','шесть','семь','восемь','девять','десять','одиннадцать','двенадцать','тринадцать','четырнадцать','пятнадцать','шестнадцать','семнадцать','восемнадцать','девятнадцать'),
			'f' => array(1=>'одна','две'),'b' => array(1=>'одно'));
		$onesbysex['f'] = $onesbysex['f'] + $onesbysex['m'];
		$onesbysex['b'] = $onesbysex['b'] + $onesbysex['m'];
		
		$s = !isset($onesbysex[$s]) ? 'm' : $s;
		$decs = array('','десять','двадцать','тридцать','сорок','пятьдесят','шестьдесят','семьдесят','восемьдесят','девяносто');
		$huns = array('','сто','двести','триста','четыреста','пятьсот','шестьсот','семьсот','восемьсот','девятьсот');

		$sexes = array( $s, 'f', 'm', 'm', 'm' );
		$grades = array(
			0 => is_array($st) ? $st : '',
			1 => array('тысяча','тысячи','тысяч'),
			2 => array('миллион','миллиона','миллионов'),
			3 => array('миллиард','миллиарда','миллиардов'),
			4 => array('триллион','триллиона','триллионов'),
			);

		$n = ltrim($n,'0');
		if(empty($n))
			return $zero;
		
		// normalize
		$n = str_repeat('0',(18-strlen($n))%3) . $n;
		$na = str_split($n, 3);
		
		$r = '';
		$grade = strlen($n)/3;
		foreach( $na as $npart )
		{
			$grade--;
			$ones = $onesbysex[$sexes[$grade]];

			if( $npart[0] )
				$r .= $huns[$npart[0]].' ';

			$nr = (int)(substr($npart,1));
			//var_dump($npart.' '.$nr);
			$r .= isset($ones[$nr])
				? $ones[$nr] . ' '
				: $decs[$npart[1]] . ' ' . $ones[$npart[2]] . ' ';

			if( isset( $grades[$grade] ) && $grades[$grade] )
				$r .= self::plural($grades[$grade],$npart) . ' ';
		}
		
		return rtrim( $r, ' ' );
	}

	static public function _test_pluraltext_ru( )
	{
		$items = array(
			'm' => array('рубль','рубля','рублей'),
			'f' => array('копейка','копейки','копеек'),
			'b' => array('солнышко','солнышка','солнышек'),
			);
		echo 4321 . ' -> ' . tool::pluraltext_ru(4321,'b',$items['b']) . ' <br/>';
		foreach( range(0,100) as $number )
		{
			$number = rand(500,50000000);
			$qual = tool::pick_any('f','m','b');
			echo $number . ' -> ' . tool::pluraltext_ru($number,$qual,$items[$qual]) . ' <br/>';
		}
		die;
	}
	
	static public function subst( $pattern, $fields, $wrapper = '{%s}' )
	{
		if(!is_array($fields)) return $pattern;
		uksort($fields,create_function('$a,$b','return strlen($a)<strlen($b);'));
		return str_replace(
			array_map( create_function( '$a', 'return sprintf("'.$wrapper.'",$a);' ), array_keys( $fields ) ),
			array_map( 'strval', array_values( $fields ) ),
			$pattern );
	}

	static public function replace_pattern($str, $vars) {
		return str_replace(array_map( create_function( '$a', 'return ":" . $a;' ), array_keys($vars)), array_values($vars), $str);
	}

	static public function is_upload_error($file, $ignore_no_file = true) {

		if(empty($file))
			$file = UPLOAD_ERR_NO_FILE;

		$errnum = is_array($file) ? (isset($file['error']) ? $file['error'] : UPLOAD_ERR_NO_FILE) : (int)$file;

		if($ignore_no_file) {
			return !($errnum == UPLOAD_ERR_NO_FILE || $errnum == UPLOAD_ERR_OK);
		}

		return $errnum != UPLOAD_ERR_OK;
	}

	static public function upload_error($file) {
		
		$errors = array(
			UPLOAD_ERR_OK => __('There is no error, the file uploaded with success.'),
			UPLOAD_ERR_INI_SIZE => __('The uploaded file is too big.'),
			UPLOAD_ERR_FORM_SIZE => __('The uploaded file is too big.'),
			UPLOAD_ERR_PARTIAL => __('The uploaded file was only partially uploaded.'),
			UPLOAD_ERR_NO_FILE => __('No file was uploaded.'),
			UPLOAD_ERR_NO_TMP_DIR => __('Missing a temporary folder.'),
			UPLOAD_ERR_CANT_WRITE => __('Failed to write file to disk.'),
			UPLOAD_ERR_EXTENSION => __('A PHP extension stopped the file upload. ')
		);

		$errnum = is_array($file) ? (isset($file['error']) ? $file['error'] : 0) : (int)$file;

		return isset($errors[$errnum]) ? $errors[$errnum] : '';
	}

}
